#include <stdio.h>
#include <stdlib.h> 
#include <SDL2/SDL.h>

#include <functional>

#include "game.h"
#include "scenes/scenetitle.h"
#include "scenes/sceneoverworld.h"
#include "scenes/scenepause.h"
#include "entities/button.h"

Game::Game()
	: state {State(1280, 720)}, all_scenes{{ make_shared<SceneTitle>(MAIN_MENU), make_shared<SceneOverworld>(OVERWORLD), make_shared<ScenePause>(PAUSE_MENU) }}
{
	this->graphics.init(state.window_w, state.window_h);
}

Game::~Game() {
	for (auto& s : all_scenes)
		s->cleanup();
	graphics.cleanup();
	SDL_Quit();
}

void Game::init()
{
	/* start SDL2 */
	if (SDL_Init(SDL_INIT_EVERYTHING) != 0) {
		fprintf(stderr, "SDL_Init error: %s\n", SDL_GetError());
		exit(EXIT_FAILURE);
	}

	SDL_LogSetPriority(SDL_LOG_CATEGORY_CUSTOM, SDL_LOG_PRIORITY_VERBOSE);
	SDL_Log("initialized SDL2 successfully\n");

	for (auto& s : all_scenes)
		s->init(state, graphics);
	
	active_scenes.push(all_scenes[MAIN_MENU]);	
}

int Game::loop()
{
	uint32_t t1, t2;
	while (!state.quit) {
		t1 = SDL_GetTicks();

		input.query(state, active_scenes.top());
		logic.update(state, all_scenes, active_scenes, input.pressed_keys);
		graphics.render(state, active_scenes);

		t2 = SDL_GetTicks();
		state.delta_ms = (t2 - t1);
		state.frame = (state.frame + 1) % 60;
		/* set to around 60fps (1000 ms/ 60 fps = 1/16 ms^2/frame) */
		SDL_Delay(16.666f);
	}

	SDL_Log("terminated successfully\n");

	return EXIT_SUCCESS;
}